from typing import Annotated
from celery import Celery
from celery.schedules import crontab
from fastapi import APIRouter, Depends, Path, status
from sqlalchemy.ext.asyncio import AsyncSession

from scaner.api_v1.auth.dependencies import get_current_active_auth_user
from scaner.core.config.log_config import MyLogger
from scaner.core.models import ADS, SearchOrder, User, db_helper
from scaner.core.models.search_order import SearchOrder

from scaner.tasks import tasks
from . import crud, schemas
from .dependencies import get_scrapper_by_order_id, order_by_id
from .utils.ads_scrap import ADSScrapper

router = APIRouter(tags=["crawl"])

main_logger = MyLogger("main")
logger = main_logger.getChild("scrap")  # type: ignore


@router.post("/get_catalog/")
async def update_root_rubric(
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    logger.info("Обновление рубрикатора с сайта")

    task: Celery.Task = tasks.run_crawling.delay()
    return {"result": "Добавлено в очередь", "task_id": task.id}


@router.get("/get_catalog/check/{task_id}/")
def check_crawling_task(
    task_id: str,
    user: User = Depends(get_current_active_auth_user),
):
    result = tasks.run_crawling.AsyncResult(task_id)

    if result.ready():
        return {"status": "complete"}
    else:
        return {"status": "pending"}


@router.get("/get_catalog/")
async def get_last_rubrics(
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    logger.info("Загрузка последнего рубрикатора из базы")

    if rubrics := await crud.get_last_rubricator(session=session):
        return {"status": "Success", "data": rubrics}

    return {"status": "Failure", "data": None}


@router.post("/", status_code=status.HTTP_200_OK)
async def create_search_order(
    data: schemas.SearchOrderCreate,
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    logger.info("Сбор объявлений")

    order: SearchOrder = await crud.order_create(
        user=user,
        order_in=data,
        session=session,
    )

    return {"result": "Success", "order_id": order.id}


@router.post("/now/{order_id}", status_code=status.HTTP_200_OK)
def start_scraping_now(
    order_id: Annotated[int, Path],
    user: User = Depends(get_current_active_auth_user),
):
    task = tasks.run_scraping.delay(order_id=order_id)
    logger.info(f"задача добавлена в очередь. id:{task.id}")

    return {
        "status": "Добавлено в очередь",
        "task_id": task.id,
    }


@router.post(
    "/schedule/{order_id}",
    status_code=status.HTTP_200_OK,
)
def schedule_scraping(
    order_id: Annotated[int, Path],
    user: User = Depends(get_current_active_auth_user),
):
    hour = "10"
    minute = "30"
    day_of_week = "tue,thu"

    schedule = crontab(
        hour=hour,
        minute=minute,
        day_of_week=day_of_week,
    )

    task_name = f"{user.id}-add-evert-{day_of_week}-at-{hour}-{minute}"

    tasks.add_periodic_task(
        task_name=task_name,
        task_func=tasks.run_scraping,
        schedule=schedule,
        args=(order_id,),
    )

    return {
        "status": "Запуск по расписанию запланирован",
        "task_name": task_name,
    }


@router.delete("/schedule/", status_code=status.HTTP_204_NO_CONTENT)
def delete_schedule(
    task_name: str,
    user: User = Depends(get_current_active_auth_user),
):
    tasks.delete_periodic_task(task_name)

    return {"status": "Success"}


@router.get("/check/{task_id}/")
def check_scraping_task(
    task_id: Annotated[str, Path],
    user: User = Depends(get_current_active_auth_user),
):
    result = tasks.run_crawling.AsyncResult(task_id)

    if result.ready():
        return {"status": "complete"}
    else:
        return {"status": "pending"}


@router.get(
    "/orders/",
    response_model=list[schemas.SearchOrderRead],
    status_code=status.HTTP_200_OK,
)
async def get_orders_for_current_user(
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    return await crud.get_orders_for_current_user(user=user, session=session)


@router.delete(
    "/orders/{id}",
    status_code=status.HTTP_204_NO_CONTENT,
)
async def delete_order(
    order: SearchOrder = Depends(order_by_id),
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    await crud.delete_order(order=order, session=session)
    return {"status": "Success"}


@router.get(
    "/ads/{order_id}/",
    response_model=list[schemas.ADSDataRead],
    status_code=status.HTTP_200_OK,
)
async def get_ads_by_order(
    order: SearchOrder = Depends(order_by_id),
    user: User = Depends(get_current_active_auth_user),
    session: AsyncSession = Depends(db_helper.get_async_session),
):
    return await crud.get_ads_by_order(order=order, session=session)
